package androidserver.engine;

import java.util.ArrayList;
import java.util.List;

import androidserver.matlabprocessor.matlabcontrol.MatlabConnectionException;
import androidserver.matlabprocessor.matlabcontrol.MatlabConnectionListener;
import androidserver.matlabprocessor.matlabcontrol.RemoteMatlabProxy;
import androidserver.matlabprocessor.matlabcontrol.RemoteMatlabProxyFactory;

public class MatlabConnectionPool {
	// Number of initial connections to make.
	private static int INITIAL_CONNECTION_NR = 3;
	// A list of available connections for use.
	private List<RemoteMatlabProxy> availableConnections = new ArrayList<RemoteMatlabProxy>();
	// A list of connections being used currently.
	private List<RemoteMatlabProxy> usedConnections = new ArrayList<RemoteMatlabProxy>();

	private RemoteMatlabProxyFactory factory = new RemoteMatlabProxyFactory();

	// Constructor
	public MatlabConnectionPool() throws MatlabConnectionException {

		//Create proxy factory, receives proxy
		factory.addConnectionListener(new MatlabConnectionListener()
		{
			//When the connection is established, store the proxy
			public void connectionEstablished(RemoteMatlabProxy proxy)
			{
				System.out.println("connectionEstablished  " + proxy);
				availableConnections.add(proxy);
			}

			//When the connection is lost, null the proxy
			public void connectionLost(RemoteMatlabProxy proxy)
			{
				System.out.println("connectionLost  " + proxy);
				removeProxy(proxy);
			}
		});
		
		for (int cnt = 0; cnt < INITIAL_CONNECTION_NR; cnt++) {
			// Add a new connection to the available list.
			requestProxy();
		}
	}
	
	public void requestProxy() {
		try
		{
			//Request a proxy, to be received by MatlabConnectionListener
			System.out.println("requestProxy elott");
			factory.getProxy();
			System.out.println("requestProxy utan");
		}
		catch (MatlabConnectionException exc)
		{
			System.out.println(exc);
		}
	}

	public synchronized RemoteMatlabProxy checkOut(){
		RemoteMatlabProxy proxy = null;

		if (availableCount() == 0) {
			System.out.println("new connection requested");
			// out of connections. Create one more.
			requestProxy();
		}
			// Connections exist!
			// Get a connection object
			proxy = availableConnections.get(availableConnections.size()-1);
			// Remove it from the available list.
			availableConnections.remove(proxy);
			// Add it to the used list.
			usedConnections.add(proxy);

		// Either way, we should have a connection object now.
		return proxy;
	}

	public synchronized void checkIn(RemoteMatlabProxy c) {
		if (c != null) {
			// Remove from used list.
			usedConnections.remove(c);
			// Add to the available list
			availableConnections.add(c);
		}
	}
	
	public synchronized void removeProxy(RemoteMatlabProxy c) {
		if (c != null) {
			// Remove from used list.
			availableConnections.remove(c);
		}
	}

	public int availableCount() {
		return availableConnections.size();
	}

}
